home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 6 / CU Amiga Magazine's Super CD-ROM 06 (1996)(EMAP Images)(GB)(Track 1 of 4)[!][issue 1997-01].iso / cucd / online / fidonetts / 3csrc.lzh / 3to2.c < prev    next >
C/C++ Source or Header  |  1992-07-12  |  10KB  |  390 lines

  1. /*
  2.  * type 3 ASCII to type 2 packet converter
  3.  * Public Domain
  4.  *
  5.  * command line arguments:  <name-of-type-3-ASCII-pkt> <name-of-type-2-pkt>
  6.  *
  7.  * this needs heavier error checking and some prettying up before it
  8.  * "real" use...should do in a pinch, though.
  9.  *
  10.  */
  11.  
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <io.h>
  18. #include <fcntl.h>
  19. #include <share.h>
  20. #include "3mail.h"
  21.  
  22. struct address {
  23.   unsigned int
  24.         zone,net,node,point;
  25.   char domain[9];
  26. };
  27.  
  28. struct privdata {
  29.   int handle;
  30.   char *fname;
  31.   struct address me;
  32.   struct address from;
  33.   struct address to;
  34. };
  35.  
  36. /* Packet header structure per FSC-0045 */
  37.  
  38. struct pkthdr2 {
  39.     unsigned int
  40.         onode,
  41.         dnode,
  42.         opoint,
  43.         dpoint;
  44.     char
  45.         zeros[8];
  46.     unsigned int
  47.         subver,
  48.         version,
  49.         onet,
  50.         dnet;
  51.     char
  52.         product,
  53.         rev_lev,
  54.         password[8];
  55.     unsigned int
  56.         ozone,
  57.         dzone;
  58.     char
  59.         odomain[8],
  60.         ddomain[8];
  61.     long
  62.         specific;
  63. };
  64.  
  65. extern int parse_addr3 (char *addr3,struct address *addr);  /* 3supp.c */
  66. extern char * type3a_2_fido (char *a,int sea);              /* 3supp.c */
  67.  
  68.  
  69.  
  70. int import_3msg (void *priv,PHDR3 *pkt3,MHDR3 *msg3,char *text,
  71.                  int textlen,int *error) {
  72.  
  73.   /* this function is called to import/forward the message
  74.    * in this case, it writes a header and message text to
  75.    * a type 2 packet.
  76.    */
  77.  
  78.   struct privdata *pd;
  79.   char             pmsg[192],*p,*pp;
  80.   unsigned int     x;
  81.   struct address   addr;
  82.   TAG3            *info;
  83.   long             pos;
  84.   static long      nummsgs = 0L;
  85.  
  86.   pd = (struct privdata *)priv;
  87.   if((!msg3->to && !msg3->area && !pkt3->area) || !msg3->date ||
  88.       !msg3->from || !msg3->id) {
  89.     *error = BADPKTHDR3;
  90.     return *error;
  91.   }
  92.   *error = NOERR3;
  93.  
  94.   memset (pmsg, 0, 192);
  95.   *pmsg = 0x02;
  96.   pmsg[1] = 0x00;
  97.  
  98.   if(!parse_addr3(msg3->from,&addr)) {
  99.     memcpy (&pmsg[2], &addr.node, 2);
  100.     memcpy (&pmsg[6], &addr.net, 2);
  101.   }
  102.   else {
  103.     memcpy (&pmsg[2], &pd->from.node, 2);
  104.     memcpy (&pmsg[6], &pd->from.net, 2);
  105.   }
  106.   if(!parse_addr3(msg3->to,&addr)) {
  107.     memcpy (&pmsg[4], &addr.node, 2);
  108.     memcpy (&pmsg[8], &addr.net, 2);
  109.   }
  110.   else {
  111.     memcpy (&pmsg[4], &pd->to.node, 2);
  112.     memcpy (&pmsg[8], &pd->to.net, 2);
  113.   }
  114.   x = 0;
  115.   info = msg3->head;
  116.   while(info) {
  117.     if(info->tag && !stricmp(info->tag,"PRIV")) {
  118.       x |= 1;
  119.       break;
  120.     }
  121.     info = info->next;
  122.   }
  123.   memcpy (&pmsg[10], &x, 2);
  124.   x = 0;
  125.   memcpy (&pmsg[12], &x, 2);
  126.   pp = type3a_2_fido (msg3->date,1);
  127.   memcpy (&pmsg[14], pp, 20);
  128.   p = &pmsg[34];
  129.   if(msg3->to && *msg3->to != '@' && (pp = strchr(msg3->to,'@')) != NULL) {
  130.     strncpy(p,msg3->to,min(35,(int)pp - (int)msg3->to));
  131.   }
  132.   else strcpy(p,"All");
  133.   x = 34;
  134.   while (*p) {
  135.     x++;
  136.     p++;
  137.   }
  138.   p++;
  139.   x++;
  140.   if(msg3->from && *msg3->from != '@' && (pp = strchr(msg3->from,'@')) != NULL) {
  141.     strncpy (p, msg3->from, min(35,(int)pp - (int)msg3->from));
  142.   }
  143.   else strcpy(p,"Sysop");
  144.   while (*p) {
  145.     x++;
  146.     p++;
  147.   }
  148.   x++;
  149.   p++;
  150.   if(msg3->subj) {
  151.     strncpy(p,msg3->subj,71);
  152.   }
  153.   while (*p) {
  154.     x++;
  155.     p++;
  156.   }
  157.   x++;
  158.   p++;
  159.   write (pd->handle, pmsg, x);
  160.  
  161.   if(pkt3->area) {
  162.     write(pd->handle,"AREA:",5);
  163.     write(pd->handle,pkt3->area,strlen(pkt3->area));
  164.     write(pd->handle,"\r",1);
  165.   }
  166.   else if(msg3->area) {
  167.     write(pd->handle,"AREA:",5);
  168.     write(pd->handle,msg3->area,strlen(msg3->area));
  169.     write(pd->handle,"\r",1);
  170.   }
  171.   write(pd->handle,"\01MSGID: ",8);
  172.   if(*msg3->id != ' ') write(pd->handle,msg3->id,strlen(msg3->id));
  173.   else {
  174.     pp = strchr(msg3->from,'@');
  175.     if(pp) pp++;
  176.     else pp = msg3->from;
  177.     write(pd->handle,pp,strlen(pp));
  178.     write(pd->handle,msg3->id,strlen(msg3->id));
  179.   }
  180.   write(pd->handle,"\r",1);
  181.   if(msg3->ref) {
  182.     write(pd->handle,"\01REPLY: ",8);
  183.     write(pd->handle,msg3->ref,strlen(msg3->ref));
  184.     write(pd->handle,"\r",1);
  185.   }
  186.   info = msg3->head;
  187.   while(info) {
  188.     if(info->tag) {
  189.       write(pd->handle,"\01",1);
  190.       write(pd->handle,info->tag,strlen(info->tag));
  191.     }
  192.     else if(info->data) write(pd->handle,"\01NOTAG",6);
  193.     if(info->data) {
  194.       write(pd->handle,":",1);
  195.       write(pd->handle,info->data,strlen(info->data));
  196.     }
  197.     if(info->tag || info->data) write(pd->handle,"\r",1);
  198.     info = info->next;
  199.   }
  200.  
  201.   write(pd->handle,text,textlen - 1);
  202.   write(pd->handle,"\0\0",3);
  203.   pos = tell(pd->handle);
  204.   if(pos) lseek(pd->handle,pos - 2L,SEEK_SET);
  205.  
  206.   printf("%ld\r",++nummsgs);
  207.   return 0;
  208. }
  209.  
  210.  
  211. int appendin_3msg (void *priv,PHDR3 *phdr,MHDR3 *mhdr,char *text,
  212.                    int textlen,int *error) {
  213.  
  214.   /* this function is called if more than one pass at the message
  215.    * text is required.  in this case, it appends the message text
  216.    * to the type 2 packet being created.
  217.    */
  218.  
  219.   struct privdata *pd;
  220.   long             pos;
  221.  
  222.   *error = NOERR3;
  223.   pd = (struct privdata *)priv;
  224.   pos = tell(pd->handle);
  225.   if(pos) lseek(pd->handle,pos - 1L,SEEK_SET);
  226.   write(pd->handle,text,textlen - 1);
  227.   write(pd->handle,"\0\0",3);
  228.   pos = tell(pd->handle);
  229.   if(pos) lseek(pd->handle,pos - 2L,SEEK_SET);
  230.   return 0;
  231. }
  232.  
  233.  
  234. int check_3pkthdr (void *priv,char *fname,PHDR3 *pkt3,int *error) {
  235.  
  236.   /* this "callback" function should check packet header and decide
  237.    * if you want to process the packet.  return 0 if so, anything
  238.    * else if not.  in this case it creates the type 2 packet and
  239.    * writes its header.  Note that data may be lost from the 3a pkt
  240.    * header to the 2 pkt header as there's no provision in 2 pkts for
  241.    * something like kludge lines...
  242.    */
  243.  
  244.   struct privdata *pd;
  245.   struct pkthdr2   pkt2;
  246.   struct address   addr;
  247.   long             pos;
  248.  
  249.   *error = NOERR3;
  250.   pd = (struct privdata *)priv;
  251.   unlink(pd->fname);
  252.   pd->handle = sopen(pd->fname,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE | S_IREAD);
  253.   if(pd->handle != -1) {
  254.     memset(&pkt2,0,sizeof(struct pkthdr2));
  255.     pkt2.version = 2;
  256.     pkt2.subver = 2;
  257.     if(pkt3->pword) strncpy(pkt2.password,pkt3->pword,8);
  258.     if(!parse_addr3(pkt3->from,&addr)) {
  259.       memcpy(&pd->from,&addr,sizeof(struct address));
  260.       pkt2.ozone = addr.zone;
  261.       pkt2.onet = addr.net;
  262.       pkt2.onode = addr.node;
  263.       strncpy(pkt2.odomain,addr.domain,8);
  264.       if(pkt3->to) {
  265.         if(parse_addr3(pkt3->to,&addr)) {
  266.           printf("\nTo: field grunged; bad packet\n");
  267.           *error = BADPKTHDR3;
  268.           return *error;
  269.         }
  270.       }
  271.       else memcpy(&addr,&pd->me,sizeof(struct address));
  272.       memcpy(&pd->to,&addr,sizeof(struct address));
  273.       pkt2.dzone = addr.zone;
  274.       pkt2.dnet = addr.net;
  275.       pkt2.dnode = addr.node;
  276.       pkt2.dpoint = addr.point;
  277.       strncpy(pkt2.ddomain,addr.domain,8);
  278.       write(pd->handle,&pkt2,sizeof(struct pkthdr2));
  279.       write(pd->handle,"\0\0",3);
  280.       pos = tell(pd->handle);
  281.       if(pos) lseek(pd->handle,pos - 3L,SEEK_SET);
  282.     }
  283.     else *error = BADPKTHDR3;
  284.   }
  285.   else {
  286.     *error = NOOPEN3;
  287.     printf("\nOpen of %s failed.\n",pd->fname);
  288.   }
  289.   return *error;
  290. }
  291.  
  292.  
  293.  
  294. int check_3msghdr (void *priv,MHDR3 *msg3,int *error) {
  295.  
  296.   /* this "callback" function should check message header and decide
  297.    * if you want to process the message.  return 0 if so, anything
  298.    * else if not.  this one doesn't do anything...
  299.    */
  300.  
  301.   *error = NOERR3;
  302.   return 0;
  303. }
  304.  
  305.  
  306. void end_3msg (void *priv,PHDR3 *pkt3,MHDR3 *msg3) {
  307.  
  308.   /* make tiny seenbys to keep old type 2s from choking */
  309.  
  310.   struct privdata *pd;
  311.   long             pos;
  312.   char             seenby[81];
  313.   struct address   addr;
  314.  
  315.   if(!pkt3->area && !msg3->area) return;
  316.  
  317.   pd = (struct privdata *)priv;
  318.   pos = tell(pd->handle);
  319.   if(pos) lseek(pd->handle,pos - 1L,SEEK_SET);
  320.  
  321.   strcpy(seenby,"\rSEEN-BY");
  322.   if(!parse_addr3(msg3->from,&addr)) {
  323.     sprintf(&seenby[strlen(seenby)]," %u/%u",addr.net,addr.node);
  324.     if(addr.net != pd->from.net || addr.node != pd->from.node) {
  325.       sprintf(&seenby[strlen(seenby)]," %u/%u",pd->from.net,pd->from.node);
  326.     }
  327.   }
  328.   else {
  329.     sprintf(&seenby[strlen(seenby)]," %u/%u",pd->from.net,pd->from.node);
  330.   }
  331.   if(!parse_addr3(msg3->to,&addr)) {
  332.     sprintf(&seenby[strlen(seenby)]," %u/%u",addr.net,addr.node);
  333.     if(addr.net != pd->to.net || addr.node != pd->to.node) {
  334.       sprintf(&seenby[strlen(seenby)]," %u/%u",pd->to.net,pd->to.node);
  335.     }
  336.     if((pd->to.net != pd->me.net || pd->to.node != pd->me.node) &&
  337.        (addr.net != pd->me.net || addr.node != pd->me.node)) {
  338.       sprintf(&seenby[strlen(seenby)]," %u/%u",pd->me.net,pd->me.node);
  339.     }
  340.   }
  341.   else {
  342.     sprintf(&seenby[strlen(seenby)]," %u/%u",pd->to.net,pd->to.node);
  343.     if(pd->to.net != pd->me.net || pd->to.node != pd->me.node) {
  344.       sprintf(&seenby[strlen(seenby)]," %u/%u",pd->me.net,pd->me.node);
  345.     }
  346.   }
  347.   strcat(seenby,"\r");
  348.  
  349.   write(pd->handle,seenby,strlen(seenby));
  350.   write(pd->handle,"\0\0",3);
  351.   pos = tell(pd->handle);
  352.   if(pos) lseek(pd->handle,pos - 2L,SEEK_SET);
  353.   return;
  354. }
  355.  
  356.  
  357. int main (int argc,char *argv[]) {
  358.  
  359.   int error;
  360.   struct privdata pd;
  361.  
  362.   if(argc < 4) {
  363.     printf("\n\n3to2 packet converter\n"
  364.            "Converts type 3 ASCII packets to type 2\n"
  365.            "\nUsage:  3to2 <type3Apacket> <type2packet> <to_address>\n"
  366.            "\n<to_address> format:  Domain#Zone:Net/Node.Point\n\n");
  367.     return -1;
  368.   }
  369.  
  370.   memset(&pd,0,sizeof(struct privdata));
  371.   pd.handle = -1;
  372.   pd.fname = argv[2];
  373.   if(parse_addr3(argv[3],&pd.me)) {
  374.     printf("\nError in <to_address> \"%s\"\n",argv[3]);
  375.     return -1;
  376.   }
  377.  
  378.   printf("\n3to2 packet converter\n%s -=> %s\n",argv[1],argv[2]);
  379.  
  380.   printf("\n\n ** Converted %ld msgs\n",
  381.          process_3pkt((void *)&pd,argv[1],&error));
  382.  
  383.   if(error && error != EOP3)
  384.     error3a(error);
  385.  
  386.   if(pd.handle != -1) close(pd.handle);
  387.  
  388.   return error;
  389. }
  390.